package com.pan.lock;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;
import java.util.concurrent.locks.ReentrantLock;

/**
 *
 * 500个线程并发
 * synchronized效率要好于reentrantLock
 *
 * @author by panstark
 * @description
 * @notice
 * @date 2021/4/30
 */
@Slf4j
public class ReentrantLockDemo{

    public static ReentrantLock reentrantLock = new ReentrantLock();

    public static final int corePoolSize = 500;
    public static final int maximumPoolSize = 2000;

    private static int i=0;
    private static int j=0;

    public static void main(String[] args) {

        runReentrantLock();
        runSynchronized();

    }

    public static void runSynchronized(){
        ExecutorService executorService = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,30, TimeUnit.MINUTES,new LinkedBlockingDeque<>(500));

        long startTime = System.currentTimeMillis();
        for (int i = 0; i <5000 ; i++) {
            executorService.execute(()->{
                addSynchronized();
            });
        }
        executorService.shutdown();
        /**
         * 如果不在循环中打印，则有可能出现打印的时候，多线程还没有执行完成，出现结果不为5000
         * 其实是打印的时候，任务还没有执行完成
         */
        long endtime;
        while(true){
            if(executorService.isTerminated()){
                log.info("j:{}",j);
                endtime = System.currentTimeMillis();
                break;
            }
        }
        log.info("addSynchronized花费是时间{}",endtime-startTime);


    }

    public static void runReentrantLock(){

        ExecutorService executorService = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,30, TimeUnit.MINUTES,new LinkedBlockingDeque<>(500));
        long startTime = System.currentTimeMillis();
        for (int i = 0; i <5000 ; i++) {
            executorService.execute(()->{
                addReentrantLock();
            });
        }
        executorService.shutdown();
        long endtime;
        while(true){
            if(executorService.isTerminated()){
                log.info("i:{}",i);
                endtime = System.currentTimeMillis();
                break;
            }
        }
        log.info("addReentrantLock花费是时间{}",endtime-startTime);
    }


    /**
     * reentrantLock基本操作
     */
    public static void addReentrantLock(){
        reentrantLock.lock();
        try {
            i++;
        }finally {
            reentrantLock.unlock();
        }
    }

    public static synchronized void addSynchronized(){
        j++;
    }

}
